﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text;

namespace Shared
{
    public class SendPacket : PacketBase
    {
        #region Fields

        private BinaryWriter MemoryWriter;
        public int MergedCount = 0;

        public override byte[] Buffer
        {
            get
            {
                return base.MemoryBuffer.ToArray();
            }
        }

        public int DataSize
        {
            get
            {
                return this.Size - 5;
            }
        }

        #endregion

        #region Constructors

        public SendPacket()
        {
            this.MemoryBuffer = new MemoryStream();
            this.MemoryWriter = new BinaryWriter(MemoryBuffer);

            AddByte(0x5E);
            AddInt32(0);
        }

        #endregion

        #region Methods

        public void StartNewMergedPacket(int MoverID, uint Command)
        {
            StartNewMergedPacket(MoverID, Command, 0xFFFFFF00);
        }

        public void StartNewMergedPacket(int MoverID, uint Command, uint MainCommand)
        {
            if (this.MergedCount == 0)
            {
                AddInt32((int)MainCommand);
                AddInt32(0);
                AddInt32(1);

                this.MergedCount++;
            }
            else
            {
                if (MoverID != -1)
                {
                    this.MemoryBuffer.Seek(13, SeekOrigin.Begin);
                    AddInt16((short)MergedCount);
                    this.MemoryBuffer.Seek(0, SeekOrigin.End);
                }
            }

            AddInt32(MoverID);
            AddInt16((short)Command);
        }

        public int Send(Socket ClientSocket)
        {
            try
            {
                int OldPointer = Pointer;

                Pointer = 1;
                AddInt32(this.DataSize);
                Pointer = OldPointer;

                if (ClientSocket.Connected)
                {
                    return ClientSocket.Send(this.Buffer);
                }
                else
                {
                    return -1;
                }
            }
            catch
            {
                return -1;
            }
        }

        #region Write Methods

        public void AddByte(byte Data)
        {
            this.MemoryWriter.Write(Data);
        }

        public void AddBytes(byte[] Data)
        {
            this.MemoryWriter.Write(Data);
        }

        public void AddBool(bool Data)
        {
            this.MemoryWriter.Write(Data);
        }

        public void AddInt16(short Data)
        {
            this.MemoryWriter.Write(Data);
        }

        public void AddInt32(int Data)
        {
            this.MemoryWriter.Write(Data);
        }

        public void AddInt64(long Data)
        {
            this.MemoryWriter.Write(Data);
        }

        public void AddUInt32(uint Data)
        {
            this.MemoryWriter.Write(Data);
        }

        public void AddString(string Data)
        {
            this.AddInt32(Data.Length);
            this.AddBytes(Encoding.ASCII.GetBytes(Data));
        }

        public void AddFloat(float Data)
        {
            this.MemoryWriter.Write(Data);
        }

        public void AddFloat(double Data)
        {
            this.MemoryWriter.Write((float)Data);
        }

        #endregion

        #endregion
    }
}
